#ifndef BASE__
#define BASE__

#include <string>
#include <sstream>
#include <cstdio>

#ifdef WIN32
	#define STRCMP _stricmp
#else
	#define STRCMP strcasecmp
#endif

#define MAX(x, y)	(x > y ? x : y)
#define MIN(x, y)	(x < y ? x : y)
#define SQR(x)		(x) * (x)

#define ODM3PUL				0.8660254
#define ODM7				2.6457513
#define EPSILON				0.001
#define MAXINT				2147483647
#define BLOCKED_MULTIPLIER	2

enum Algorithms				{genetic, permutation, tabu, annealing, sequential, algorithm_unknown};
enum Areas					{philadelphia, coords, area_unknown};
static const char * AlgorithmNames[] = {"genetic", "permutation", "tabu", "annealing", "sequential"};
static const char * AreaNames[] = {"philadelphia", "coordinates"};

enum SequentialOrdering		{GLargestFirstExclude, LargestFirst, LargestFirstExclude, SmallestLast,
	GLargestFirst, GSmallestLast, Random}; ///< G means generalized (weighted sum of number of neighbours)
enum SequentialNext			{Sequential, GSD}; ///< GSD = generalized saturation degree
enum SequentialFrequency	{Smallest, Occupied, SmallestOccupied, HeaviestOccupied};
static const char * SequentialOrderingNames[] = {"nejvetsi nejdrive s odmazavanim zavislosti (vazene)", "nejvesti nejdrive",
	"nejvetsi nejdrive s odmazavanim zavislosti", "nejmensi nejpozdeji", "nejvetsi nejdrive (vazene)","nejmensi nejpozdeji (vazene)", "nahodne"}; 
static const char * SequentialFrequencyNames[] = {"nejmensi dostupna", "obsazena", "nejmensi obsazene", "nejmensi z nejvice obsazenych"};
static const char * SequentialOrderingShort[] = {"GLFE", "LF", "LFE", "SL", "GLF", "GSL", "RND"};
static const char * SequentialFrequencyShort[] = {"SF", "OF", "SOF", "SHOF"}; 

enum CoolingStrategy		{Geometric, Costa, Hurley}; ///< GSD = generalized saturation degree
static const char * CoolingNames[] = {"geometricka", "geometricka + zvysovani poctu behu kola (Costa)", "specialni snizovani teploty (Hurley)"};
static const char * CoolingShort[] = {"GEO", "COS", "HUR"};

/** Abstraktni zakladni trida pro zobrazovani informaci o prubehu algoritmu.
 */
class ProgressDisplayer {
public:
	ProgressDisplayer() {};
	virtual ~ProgressDisplayer() {};
	/** Zobrazi dany text.
	 * \param text informace o aktualnim prubehu
	 */
	virtual void DisplayText(const std::string & text) = 0;
	/** Pripraveni podkladu pro vypis informaci o dalsim algoritmu (je spousten novy algoritmus).
	 */
	virtual void NextTest() = 0;
	/** Nastaveni poctu testu.
  	 * \param count pocet testu
 	 */
	virtual void TestCount(int count) = 0;
};

std::string IntToStr(int d);
std::string DoubleToStr(double d);

#endif
